home *** CD-ROM | disk | FTP | other *** search
/ Tech Arsenal 1 / Tech Arsenal (Arsenal Computer).ISO / tek-02 / wedits22.zip / WELINE.PAS < prev    next >
Pascal/Delphi Source File  |  1991-08-13  |  7KB  |  267 lines

  1. UNIT WELine;
  2. { -- This is the Line Handling unit for WWIVEdit 2.2
  3.   -- Last Modified : 8/13/91
  4.   -- Written By:
  5.   --   Adam Caldwell
  6.   --
  7.   -- This code is limited public domain (see WWIVEDIT.PAS for details)
  8.   --
  9.   -- Known errors: None
  10.   --
  11.   -- Planned Enhancements: None
  12.   --
  13.   --}
  14. {$R-,V-,S+,B-,E-,N-}   { These Optomize things as much as possible }
  15.  
  16. INTERFACE
  17.  
  18. USES WEVars;
  19.  
  20. PROCEDURE MakeString(VAR s:LineType; ch,col:char);
  21. FUNCTION  Len(LineNum : integer):byte;
  22. FUNCTION  Character(lineNum,Column:integer):char;
  23. PROCEDURE LDelete(LineNum,index,length:integer);
  24. FUNCTION  Color(VAR s:linetype; p:integer):char;
  25. PROCEDURE LInsert(s:LineType; LineNum, index:integer);
  26. PROCEDURE StripEnd(LineNum:integer);
  27. PROCEDURE WordWrap(VAR s1:linetype; VAR s2:linetype; minx:integer);
  28. PROCEDURE InsertLine(before:integer; s:linetype);
  29. PROCEDURE DeleteLine(n:integer);
  30. FUNCTION  FirstDiff(s1,s2:LineType):integer;
  31. PROCEDURE Reformat(n:integer; movecursor:boolean);
  32. PROCEDURE InitLine(VAR s:LineType);
  33.  
  34. IMPLEMENTATION
  35.  
  36. PROCEDURE InitLine(VAR s:LineType);
  37. { Initializes a line to an empty string and sets the color attributes to 0 }
  38. VAR x:integer;
  39. BEGIN
  40.   s.l:='';
  41.   s.c:='';
  42.   s.HardCR:=TRUE;
  43. END;
  44.  
  45.  
  46. PROCEDURE MakeString(VAR s:LineType; ch,col:char);
  47. { Makes a "Line" of one charcter with the given color attribute }
  48. BEGIN
  49.   s.l[0]:=#1;
  50.   s.c[0]:=#1;
  51.   s.l[1]:=ch;
  52.   s.c[1]:=col;
  53. END;
  54.  
  55.  
  56. FUNCTION Len(LineNum : integer):byte;
  57. { Returns the length of the given LineNum }
  58. BEGIN
  59.   Len:=length(Line[lineNum]^.l)
  60. END;
  61.  
  62.  
  63.  
  64.  
  65.  
  66. FUNCTION Character(lineNum,Column:integer):char;
  67. { Returns the Character at the given Column on the Given Line }
  68. BEGIN
  69.   IF len(LineNum)>0 THEN Character:=Line[LineNum]^.l[column] ELSE Character:=#0
  70. END;
  71.  
  72.  
  73.  
  74. PROCEDURE LDelete(LineNum,index,length:integer);
  75. { Deletes from the given LineNum starting at index, length # of characters }
  76. VAR
  77.   x: integer;
  78. BEGIN
  79.   delete(Line[LineNum]^.l,index,length);
  80.   delete(Line[LineNum]^.c,index,length);
  81. END;
  82.  
  83. FUNCTION Color(VAR s:linetype; p:integer):char;
  84. { Returns the color attribute of the p'th character on the "line" S }
  85. BEGIN
  86.   Color := s.c[p]
  87. END;
  88.  
  89.  
  90.  
  91. PROCEDURE LInsert(s:LineType; LineNum, index:integer);
  92. { inserts the given string onto the given LineNum at the given index }
  93. VAR
  94.   x:integer;
  95.   t:LineType;
  96.   clr : char;
  97. BEGIN
  98. { Pad the line with blanks if needed }
  99.   IF NOT InsertMode
  100.     THEN x:=index+length(s.l)-1
  101.     ELSE x:=index-1;
  102.   WHILE (x>len(LineNum)) DO
  103.   BEGIN
  104.     IF len(LineNum)<1
  105.       THEN clr:=CurrentColor
  106.       ELSE clr:=Color(Line[LineNum]^,Len(LineNum));
  107.     MakeString(t,' ',clr);
  108.     insert(t.c,Line[LineNum]^.c,length(Line[LineNum]^.c)+1);
  109.     insert(t.l,Line[LineNum]^.l,length(Line[LineNum]^.c)+1);
  110.   END;
  111.  
  112.   IF InsertMode THEN
  113.   BEGIN
  114.     insert(s.l,Line[LineNum]^.l,index);
  115.     insert(s.c,Line[LineNum]^.c,index);
  116.   END
  117.   ELSE
  118.     FOR x:=index TO index+length(s.l)-1 DO
  119.     BEGIN
  120.       Line[LineNum]^.l[x]:=s.l[x-index+1];
  121.       Line[LineNum]^.c[x]:=s.c[x-index+1];
  122.     END;
  123. END;
  124.  
  125.  
  126.  
  127. PROCEDURE StripEnd(LineNum:integer);
  128. { Strips off the end of the given LineNum }
  129. BEGIN
  130.   WHILE Character(LineNum,len(LineNum))=' ' DO
  131.     LDelete(LineNum,len(LineNum),1);
  132. END;
  133.  
  134. PROCEDURE WordWrap(VAR s1:linetype; VAR s2:linetype; minx:integer);
  135. { strips off the last word(s) in s1 and stores it in S2 }
  136. VAR i,x:integer;
  137. BEGIN
  138.   IF minx>=Length(s1.l) THEN minx:=0;
  139.   x:=length(s1.l);                         { point X to the end of the orignal line }
  140.   IF x>LineLen THEN x:=LineLen;            { Make sure that all extra is taken off }
  141.   WHILE (x>minx) AND (NOT (s1.l[x]=' ')) DO   { Go until it finds a space or there's nothing left }
  142.     dec(x);
  143.   IF x=0 THEN x:=LineLen;
  144.   s2.l := copy(s1.l,x+1,length(s1.l)-x);   { copy the string part of it }
  145.   s2.c := copy(s1.c,x+1,length(s1.c)-x);   { copy the color part of it  }
  146.   delete(s1.l,length(s1.l)-length(s2.l)+1,length(s2.l));
  147.   delete(s1.c,length(s1.c)-length(s2.c)+1,length(s2.c));
  148. END;
  149.  
  150.  
  151.  
  152. PROCEDURE InsertLine(before:integer; s:linetype);
  153. { inserts the line s on the line before the line pointed to by before }
  154. VAR x:integer;
  155. BEGIN
  156.   IF before<=BlockStart THEN inc(blockStart);
  157.   IF before<=BlockEnd THEN inc(blockEnd);
  158.   Dispose(Line[MaxLines]);
  159.   FOR x:=MaxLines DOWNTO before DO
  160.     Line[x]:=Line[x-1];
  161.   New(Line[Before]);
  162.   Line[before]^:=s;
  163.   IF before>Highline THEN
  164.     Highline:=before+1
  165.   ELSE
  166.     Inc(Highline);
  167. END;
  168.  
  169. FUNCTION FirstDiff(s1,s2:LineType):integer;
  170. { Compares the two lines until it finds a difference in either the characters
  171.   or the colors }
  172. VAR
  173.   x:integer;
  174.   EndPoint:integer;
  175. BEGIN
  176.   IF (s1.l='') or (s2.l='') THEN FirstDiff:=1
  177.   ELSE BEGIN
  178.     IF length(s1.l)>length(s2.l) THEN EndPoint:=length(s2.l)
  179.     ELSE EndPoint := length(s1.l);
  180.     x:=1;
  181.     WHILE (x<=EndPoint) AND (s1.l[x]=s2.l[x]) AND (s1.c[x]=s2.c[x]) DO
  182.       inc(x);
  183.     FirstDiff:=x;
  184.   END
  185. END;
  186.  
  187. PROCEDURE DeleteLine(n:integer);
  188. { Removes the given line number }
  189. VAR
  190.   x:integer;
  191.   Temp : pointer;
  192. BEGIN
  193.   IF n<BlockStart THEN Dec(BlockStart);
  194.   IF n<BlockEnd THEN Dec(BlockEnd);
  195.   temp:=Line[n];
  196.   FOR x:=n TO MaxLines-1 DO
  197.     Line[x]:=Line[x+1];
  198.   Line[MaxLines]:=temp;
  199.   InitLine(Line[MaxLines]^);
  200.   IF n>Highline THEN
  201.     Highline:=n
  202.   ELSE
  203.     dec(highline);
  204. END;
  205.  
  206.  
  207.  
  208. PROCEDURE Reformat(n:integer; MoveCursor:boolean);
  209. { Reformats the text, starting at the given line. }
  210. { -- Majorly changed since 2.1 to take into account where the hard Carriage
  211.      returns are. }
  212. VAR
  213.   flag : boolean;
  214.   t : LineType;
  215.   l : integer;
  216.  
  217. BEGIN
  218.   InitLine(t);            { Initialize a temporary line }
  219.   flag:=MoveCursor;
  220.   IF Len(n)>LineLen THEN  { Split off last word onto new line }
  221.   BEGIN
  222.     flag:=cx>LineLen;
  223.     StripEnd(n);          { Erase any blank characters at the end of the line }
  224.     InsertLine(n+1,t);    { Insert a blank line }
  225.     IF Len(n)>LineLen THEN{ If this line is too long, then wordwrap }
  226.     BEGIN
  227.       WordWrap(Line[n]^,Line[n+1]^,cx);
  228.       StripEnd(n);
  229.     END;
  230.     IF flag THEN BEGIN
  231.       inc(cy);
  232.       cx:=len(cy);
  233.     END ELSE Line[n+1]^.hardCR:=false;
  234.     Line[n]^.HardCR:=false;
  235.     inc(n);
  236.   END;
  237.   WHILE NOT Line[n]^.HardCR DO
  238.   BEGIN
  239. {    Drain;                         { Drain off any keystokes waiting }
  240.     flag:=Line[n]^.l[len(n)]<>' '; { True if line will need space attached }
  241.     l:=LineLen-Len(n);             { Number of character this line can accept }
  242.     IF flag THEN dec(l);
  243.     IF l>Len(n+1) THEN BEGIN       { If the next line is less characters than }
  244.       IF flag THEN                 { can fit, then just add the whole line   }
  245.         LInsert(Line[n+1]^,n,len(n)+2)
  246.       ELSE
  247.         LInsert(Line[n+1]^,n,len(n)+1);
  248.       Line[n]^.HardCR:=Line[n+1]^.HardCR;
  249.       DeleteLine(n+1);             { Delete that old part that was just added }
  250.     END
  251.     ELSE BEGIN                     { otherwise, add one word at a time }
  252.       WHILE (l>0) AND (Line[n+1]^.l[l]<>' ') DO
  253.         dec(l);
  254.       t.l:=copy(Line[n+1]^.l,1,l-1);
  255.       t.c:=copy(Line[n+1]^.c,1,l-1);
  256.       Ldelete(n+1,1,l);
  257.       IF t.l<>'' THEN
  258.         IF flag THEN
  259.           Linsert(t,n,len(n)+2)
  260.         ELSE
  261.           Linsert(t,n,len(n)+1);
  262.       inc(n);
  263.     END;
  264.   END;
  265. END;
  266.  
  267. END.